package com.padakeji.android.ui.widget;

import android.content.Context;
import android.os.AsyncTask;
import android.support.annotation.LayoutRes;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListAdapter;
import android.widget.ListView;

import com.padakeji.android.ui.R;

import java.util.concurrent.Executors;

/**
 * Created by atanl on 2015/12/5.
 */
public class ListViewX extends ListView {

    public static abstract class AutoLoadListener<T> {
        public abstract T loadInBackground();
        public abstract void onLoadFinish(T data);
        public abstract void onLoadFail(Throwable throwable);

        private final void finish(Object data) {
            onLoadFinish((T) data);
        }
    }

    private OnScrollListener mOnScrollListener;
    private AutoLoadListener mAutoLoadListener;

    private boolean mIsAutoLoadEnable = false;
    private int mAutoLoadThreshold = 0;
    private View mLoadingView; // 自动加载被触发之后，显示在ListView底部的加载提示。
    private boolean mIsFullyLayout = false;

    public ListViewX(Context context) {
        this(context, null);
    }

    public ListViewX(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.listViewStyle);
    }

    public ListViewX(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {

        initDefaultLoadingView();

        OnScrollListener onScrollListener = new OnScrollListener() {
            private Boolean isLoading = false;

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                if (mOnScrollListener != null) {
                    mOnScrollListener.onScrollStateChanged(view, scrollState);
                }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (mOnScrollListener != null) {
                    mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
                }
                if (mIsAutoLoadEnable) {
                    synchronized (isLoading) {
                        if (isLoading) {
                            return;
                        }
                        // 保证更改自动加载启动阀值mAutoLoadThreshold时，currentAutoLoadThreshold保持不变。
                        int currentAutoLoadThreshold = mAutoLoadThreshold;

                        int headerViewsCount = getHeaderViewsCount();
                        int footerViewsCount = getFooterViewsCount();
                        int lastVisibleItem = headerViewsCount + firstVisibleItem + visibleItemCount;
                        if (totalItemCount - footerViewsCount - lastVisibleItem <= currentAutoLoadThreshold + 1) {
                            new AsyncTask<Void, Void, Object>() {
                                // 其实是对mLoadingView的引用。保证切换mLoadingView时，currentLoadingView保持不变。
                                private View currentLoadingView;

                                @Override
                                protected void onPreExecute() {
                                    super.onPreExecute();
                                    isLoading = true;
                                    showLoadingView();
                                }

                                @Override
                                protected Object doInBackground(Void... params) {
                                    if (mAutoLoadListener != null) {
                                        try {
                                            return mAutoLoadListener.loadInBackground();
                                        } catch (Exception e) {
                                            try {
                                                mAutoLoadListener.onLoadFail(e);
                                            } catch (Exception e1) {
                                                e1.printStackTrace();
                                            }
                                        }
                                    }
                                    return null;
                                }

                                @Override
                                protected void onPostExecute(Object o) {
                                    dismissLoadingView();
                                    if (mAutoLoadListener != null) {
                                        try {
                                            mAutoLoadListener.finish(o);
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                    }
                                    isLoading = false;
                                }

                                private void showLoadingView() {
                                    if (mLoadingView != null) {
                                        currentLoadingView = mLoadingView;
                                        addFooterView(currentLoadingView);
                                    }
                                }

                                private void dismissLoadingView() {
                                    if (currentLoadingView != null) {
                                        removeFooterView(currentLoadingView);
                                        currentLoadingView = null;
                                    }
                                }

                            }.executeOnExecutor(Executors.newSingleThreadExecutor());
                        }
                    }
                }
            }

        };
        super.setOnScrollListener(onScrollListener);
    }

    private void initDefaultLoadingView() {
        setLoadingView(R.layout.padaui_list_view_loading);
    }

    // 这样重载这个方法，其实是被逼的。
    @Override
    public void setAdapter(ListAdapter adapter) {
        if (adapter != null) {
            View v = new View(getContext());
            addFooterView(v);
            super.setAdapter(adapter);
            removeFooterView(v);
        }
    }

    /**
     * 设置自动加载数据时，显示在ListView底部的加载提示。
     * @param loadingView
     */
    public void setLoadingView(View loadingView) {
        this.mLoadingView = loadingView;
    }

    public void setLoadingView(@LayoutRes int layoutResId) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        View loadingView = inflater.inflate(layoutResId, this, false);
        setLoadingView(loadingView);
    }

    @Override
    public void setOnScrollListener(OnScrollListener l) {
        this.mOnScrollListener = l;
    }


    public void setAutoLoadListener(AutoLoadListener l) {
        this.mAutoLoadListener = l;
    }

    public void enableAutoLoad() {
        enableAutoLoad(0);
    }

    /**
     * 开启自动加载功能。threshold表示触发自动加载的阀值。
     * @param threshold 表示最多有多少个item未展示时，会触发自动加载。
     */
    public void enableAutoLoad(int threshold) {
        if (threshold > 0) {
            mAutoLoadThreshold = threshold;
        }
        mIsAutoLoadEnable = true;
    }

    public void disableAutoLoad() {
        mIsAutoLoadEnable = false;
    }

    public void enableFullyLayout() {
        mIsFullyLayout = true;
        invalidate();
        requestLayout();
    }

    public void disableFullyLayout() {
        mIsFullyLayout = false;
        invalidate();
        requestLayout();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mIsFullyLayout) {
            int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
            heightMeasureSpec = expandSpec;
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

}
